﻿using System;
using System.CodeDom.Compiler;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Management;
using System.Reactive;
using System.Reflection;
using System.Reflection.Metadata;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Effects;
using System.Windows.Media.Media3D;
using System.Windows.Threading;
using DynamicData;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Serilog;
using SimpleTool.Server;
using SimpleTool.TransformComponent;
using Supabase.Postgrest;
using static SimpleTool.ActivityUnit.ActivitySectionModel;
using static SimpleTool.TransformComponent.CustomMessageBox;

namespace SimpleTool.ActivityUnit
{
    class ActivityDetetor
    {
        private static readonly ILogger Logger = Log.ForContext<ActivityDetetor>();

        private static class AdvanceInfo
        {
            public static string PRDFLAG = string.Empty;

            public static string IMEI = string.Empty;

            public static string SN = string.Empty;

            public static string DOID = string.Empty;

            public static string? QRCODE_1 = string.Empty;

            public static string? QRCODE_2 = string.Empty;

            public static List<string> QRCODE = [];

            public static void Init()
            {
                IMEI = string.Empty;
                SN = string.Empty;
                DOID = string.Empty;
            }
        }

        private sealed class CacheBlueTooth : IDisposable
        {
            public Regex Regex = new Regex("(?-i)((?:[0-9a-zA-Z]{2}[:-]+){4,}[0-9a-zA-Z]{2})\\W*(\\d+)*");

            public string Rc_CacheBlueSerialPort = string.Empty; // 保存蓝牙串口名

            public string Rc_CacheBluetoothAddress = string.Empty; // 保存蓝牙地址

            public string? Rc_CacheBlueCommandSignal = null; // 蓝牙信号值

            public bool Rc_CacheBlueCommandCommit = false; // 保存完整蓝牙指令

            public Action<string> BlueOutput = (content) => { }; 

            public SerialPort BluetoothSerial = new() //蓝牙串口
            {
                BaudRate = 115200,
                DataBits = 8,
                Parity = Parity.None,
                StopBits = StopBits.Two,
                Handshake = Handshake.None
            };

            public async void DataReceivedEventArgs(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                if (BluetoothSerial.IsOpen)
                {
                    string content = BluetoothSerial.ReadExisting();
                    await Match(content);
                    Logger.DebudElite("-->蓝牙收到信息", content);
                    BlueOutput.Invoke(content);
                }
            }

            public async Task Match(string content)
            {
                await Task.Run(() =>
                {
                    var BlueMatch = Regex.Match(content);

                    if (BlueMatch.Groups.Count == 2)
                    {
                        Rc_CacheBluetoothAddress = BlueMatch.Groups[1].Value;
                    }
                    else if (BlueMatch.Groups.Count >= 3)
                    {
                        Rc_CacheBluetoothAddress = BlueMatch.Groups[1].Value;
                        Rc_CacheBlueCommandSignal = BlueMatch.Groups[2].Value;
                    }
                });
            }

            public bool Open()
            {
                try
                {
                    if (!BluetoothSerial.IsOpen)
                    {
                        BluetoothSerial.Open();

                        if (BluetoothSerial.IsOpen)
                        {
                            BluetoothSerial.DataReceived += DataReceivedEventArgs;
                            return true;
                        }
                        else
                        {
                            BluetoothSerial.DataReceived -= DataReceivedEventArgs;
                            return false;
                        }
                    }
                    else
                    {
                        return true;
                    }
                } 
                catch (Exception error)
                {
                    Logger.ErrorElite($"serial open error: {error.Message}, port: {BluetoothSerial.PortName}");
                    return false;
                }
            }

            public void Close(int type = 0)
            {
                switch (type)
                {
                    case 0:
                        if (BluetoothSerial.IsOpen)
                        {
                            BluetoothSerial.Close();
                        }
                        break;
                    case 1:
                        if (BluetoothSerial.IsOpen)
                        {
                            BluetoothSerial.Close();
                            BluetoothSerial.Dispose();
                        }
                        break;
                }
            }

            public bool Write(string command)
            {
                if (BluetoothSerial.IsOpen)
                {
                    Logger.WarningElite("send blue command: ", command);
                    BluetoothSerial.Write(command + "\r\n");
                    return true;
                }
                else
                {
                    Logger.WarningElite("blue serial not open");
                    return false;
                }
                
            }

            public void Dispose()
            {
                GC.SuppressFinalize(this);
            }

            ~CacheBlueTooth()
            {
                if (BluetoothSerial.IsOpen) BluetoothSerial.Close();
                BluetoothSerial.Dispose();
                BluetoothSerial.DataReceived -= DataReceivedEventArgs;
            }
        }

        private sealed class ActivityProductTestState
        {

            //节点等待
            public bool St_StepAwait = false;

            //蓝牙串口名获取进入标识
            public bool St_Bluetooth_SerialPort_Get = false;

            //蓝牙地址获取进入标识
            public bool St_Bluetooth_Address_Apply = false;

            //蓝牙地址确认标识
            public bool St_Bluetooth_Address_Question = false;

            //蓝牙代理等待标识
            public bool St_DelAwait_Reset_Watch = false;

            //节点报错标识
            public bool St_RunCatch_Happend = false;

            //最大重试次数标识
            public bool St_MaxTry_SoFar = false;

            //是否直接执行，需要拼接的指令则等待拼接
            public bool St_DirectExecute = true;

            //数据读取开关
            public bool DataStreamSwitch = false;

            //是否允许打开蓝牙串口，该标志决定是否指定蓝牙串口号
            public bool IsBluetoothBoard = false;

            //是否传承匹配值
            public bool IsHandDownValue = false;

            //获取新流程至指令发送中间阶段，控制Run方法接收文本的状态，默认不获取，发送指令临近时打开状态，避免数据污染
            public bool ReceiveAdvanceFlag = false;
        }

        private sealed class ActivityProductTestRecord
        {
            public string Rc_CurrentApplyCommand = string.Empty;

            public string Rc_ExecuteAtrribute = string.Empty; // 报错节点中文名称

            public ConcurrentBag<string> Rc_SerialPortoutPut = []; // 手机串口输出

            public List<string> Rc_ProcessValue = []; // 经过数据处理类型匹配的有效值

            public readonly Dictionary<string, List<string>> Rc_CachePassValue = []; // 保存通过值

            public ConcurrentBag<string> Rc_CollectedFields = []; // 保存通过字段

            public MultilAtrributeStruct? Rc_Atrribute = null; // 保存当前节点信息

            public List<FieldInfo> Rc_CanCheckFields = []; //保存关键有效字段，对应 Rc_CollectedFields

            public List<FieldInfo> Rc_ValidFiedls = []; //保存有效字段

            public CustomMessageBox.Invoke? QuestioningReturn; // 保存弹框回执信息

            public string Rc_StepPossibleCause = string.Empty; // 可能原因

        }

        private sealed class ActivityProductTestValue
        {
            public int MaxRetryCount = 2; // 最大重试次数

            public int CurRetryCount = 0; // 当前重试次数

            public int TimeoutMs = 7000; // 节点超时时间

            public string CurBluethAccording = string.Empty; //蓝牙拼接字符

            public string CurAddtionAccording = string.Empty; //指令拼接字符
        }

        private IPowerPlant PowerPlantServer;

        private IActivityDetetorAssist ActivityDetatorServer;

        private DispatcherTimer ReuseOutTimer = new ();

        private CacheBlueTooth ProductBlueCache = new ();

        private ConcurrentDictionary<string, ActivityProductTestState> ProductTestState = new ();

        private ConcurrentDictionary<string, ActivityProductTestRecord> ProductTestRecord = new ();

        private ConcurrentDictionary<string, ActivityProductTestValue> ProductTestValue = new();

        private readonly MessageProPlant? MessagePro = null;

        //当前流程
        private readonly ConcurrentStack<string> Safety_Step = new();

        //流程状态
        public readonly ConcurrentStack<bool> Safety_ProcessRunning = new();

        //测试节点名称
        public readonly ConcurrentStack<bool> Safety_StepRunning = new();

        //工序索引
        private int WorkIndex = 0;

        //遗留值
        private static string? HandDownValue = null;

        //是否长时间步骤，例如刷卡，程序已停止但是设备可能还在运行
        private bool isLongTimeAtrribute = false;

        public ActivityDetetor(MessageProPlant messagePro)
        {
            App app = (App)Application.Current;
            PowerPlantServer = app.RetailSection.GetRequiredService<IPowerPlant>();
            ActivityDetatorServer = app.RetailSection.GetRequiredService<IActivityDetetorAssist>();

            ProductBlueCache.BlueOutput = (content) =>
            {
                if (Safety_Step.TryPeek(out string? Step) &&
                    ProductBlueCache.Rc_CacheBlueCommandSignal is not null and string signal &&
                    ProductTestRecord.TryGetValue(Step, out ActivityProductTestRecord? _ProductTestRecord))
                {
                    
                    TryAdd(_ProductTestRecord.Rc_CurrentApplyCommand, signal);

                    _ProductTestRecord.Rc_SerialPortoutPut.Add(content);
                }
            };
            MessagePro = messagePro;
            ReuseOutTimer.Interval = TimeSpan.FromSeconds(1);
            WeakEventManager<DispatcherTimer, EventArgs>.AddHandler(ReuseOutTimer, nameof(DispatcherTimer.Tick), (sender, e) => Run(string.Empty));
        }

        private void GetAssistAtrribute(MultilAtrributeStruct process)
        {
            if (ProductTestValue.TryGetValue(process.Step, out ActivityProductTestValue? _ProductTestValue))
            {

                if (process.BluethAccording is not null and string _BluethAccording)
                {
                    _ProductTestValue.CurBluethAccording = _BluethAccording;
                }
                else
                {
                    _ProductTestValue.CurBluethAccording = ":";
                }

                if (process.AddtionAccording is not null and string _AddtionAccording)
                {
                    _ProductTestValue.CurAddtionAccording = _AddtionAccording;
                }

                if (process.TimeoutMs is not null and int _TimeoutMs)
                {
                    _ProductTestValue.TimeoutMs = _TimeoutMs;
                }

                if (process.MaxRetryCount is not null and int _MaxRetryCount)
                {
                    _ProductTestValue.MaxRetryCount = _MaxRetryCount; ;
                }
            }

            if (ProductTestState.TryGetValue(process.Step, out ActivityProductTestState? _ProductTestState))
            {

                if (process.IsCombination is not null and bool _IsCombination)
                {
                    _ProductTestState.St_DirectExecute = !_IsCombination;
                }

                if (process.IsBluetoothBoard is not null and bool _IsBluetoothBoard)
                {
                    _ProductTestState.IsBluetoothBoard = _IsBluetoothBoard; ;
                }

                if (process.IsHandDownValue is not null and bool _IsHandDownValue)
                {
                    _ProductTestState.IsHandDownValue = _IsHandDownValue; ;
                }
            }
            Logger.DebudElite("_assist_atrribute_end_");
        }

        public async Task ReadyRunning(List<MultilAtrributeStruct> multilAtrributes)
        {
            if (!ReuseOutTimer.IsEnabled) ReuseOutTimer.Start();

            Stopwatch longTimeWatch = Stopwatch.StartNew();
            bool isExeption = false;

            await Task.Run(async () => {

                foreach (var process in multilAtrributes)
                {
                    bool ExcuteCommand = false;
                    Safety_Step.Push(process.Step);

                    if (Safety_Step.TryPeek(out string? Step))
                    {
                        ProductTestState.AddOrUpdate(Step, new ActivityProductTestState(), (key, oldValue) => new ActivityProductTestState());
                        ProductTestRecord.AddOrUpdate(Step, new ActivityProductTestRecord(), (key, oldValue) => new ActivityProductTestRecord());
                        ProductTestValue.AddOrUpdate(Step, new ActivityProductTestValue(), (key, oldValue) => new ActivityProductTestValue());

                        ProductTestRecord[Step].Rc_Atrribute = process;
                        ProductTestRecord[Step].Rc_ValidFiedls = process.GetFields(1);
                        ProductTestRecord[Step].Rc_CanCheckFields = [.. ProductTestRecord[Step].Rc_ValidFiedls
                                                                        .Where(x => ActivityAssistBehivor.Behivor.fieldCanCheckNames.Contains(x.Name))];
                        ProductTestRecord[Step].Rc_CurrentApplyCommand = process.Command;

                        if (process.SendDelayMs is not null and int _SendDelayMs)
                        {
                            await Task.Delay(_SendDelayMs);
                        }
                        else
                        {
                            await Task.Delay(100);
                        }

                        GetAssistAtrribute(process);

                        ProductTestState[Step].ReceiveAdvanceFlag = true;

                        //等待拼接。不直接执行
                        if (!ProductTestState[Step].St_DirectExecute)
                        {
                            Stopwatch directWatch = Stopwatch.StartNew();
                            while (Safety_ProcessRunning.TryPeek(out bool St_ProcessRunning0) && St_ProcessRunning0)
                            {
                                if (directWatch.ElapsedMilliseconds > ProductTestValue[Step].TimeoutMs)
                                {
                                    MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"指令拼接超时"));
                                    break;
                                }
                                if (ProductTestState[Step].St_DirectExecute) break;
                                await Task.Delay(100);
                            }
                        }

                        //上一次长时间流程失败后则增加等待，避免产测执行后设备流程未结束得情况
                        if (isLongTimeAtrribute)
                        {
                            int waitTime = 1;
                            MessagePro?.Invoke(new Check(MessageProPlantType.Message,
                                        $"上一个耗时流程可能未结束，等待中，稍后进行操作"));
                            while (true)
                            {
                                MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"等待 {waitTime} 秒"));
                                if (longTimeWatch.ElapsedMilliseconds > 7000)
                                {
                                    isLongTimeAtrribute = false;
                                    break;
                                }
                                waitTime++;
                                await Task.Delay(1000);
                            }
                        }

                        if (ProductTestState[Step].IsBluetoothBoard)
                        {
                            ExcuteCommand = ProductBlueCache.Write(ProductTestRecord[Step].Rc_CurrentApplyCommand.Trim());
                        }
                        else
                        {
                            ExcuteCommand = PowerPlantServer.Execute(ProductTestRecord[Step].Rc_CurrentApplyCommand.Trim());
                        }

                        Logger.DebudElite("last command: ", ProductTestRecord[Step].Rc_CurrentApplyCommand.Trim());

                        if (ExcuteCommand)
                        {
                            MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"正在进行:  {Step}, 请注意是否需要手动操作，执行指令: {ProductTestRecord[Step].Rc_CurrentApplyCommand}"));

                            MessagePro?.Invoke(new Check(MessageProPlantType.HeartBeats, $"结束测试"));

                            //以 St_ProcessRunning1 为依据，控制结果输出
                            Stopwatch TimeoutMswatch = Stopwatch.StartNew();
                            while (Safety_ProcessRunning.TryPeek(out bool St_ProcessRunning1) && St_ProcessRunning1)
                            {
                                if (Safety_StepRunning.TryPeek(out bool St_StepRunning) && St_StepRunning)
                                {
                                    Safety_StepRunning.Push(false);
                                    MessagePro?.Invoke(new Check(MessageProPlantType.Message | MessageProPlantType.Success, $"{Step}->测试通过", WorkIndex));
                                    WorkIndex++;
                                    break;
                                }

                                if (ProductTestState[Step].St_DelAwait_Reset_Watch)
                                {
                                    TimeoutMswatch = Stopwatch.StartNew();
                                    ProductTestState[Step].St_StepAwait = false;
                                    ProductTestState[Step].St_DelAwait_Reset_Watch = false;
                                    MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"重置手表状态，删除等待"));
                                }

                                if (TimeoutMswatch.ElapsedMilliseconds > ProductTestValue[Step].TimeoutMs && !ProductTestState[Step].St_StepAwait)
                                {
                                    if (St_StepRunning)
                                    {
                                        MessagePro?.Invoke(new Check(MessageProPlantType.Message | MessageProPlantType.Success, $"{Step}->测试通过", WorkIndex));
                                        Safety_StepRunning.Push(false);
                                        WorkIndex++;
                                    }
                                    else
                                    {
                                        if (ProductTestValue[Step].MaxRetryCount > ProductTestValue[Step].CurRetryCount)
                                        {
                                            MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"{Step}->正在重试"));
                                            TimeoutMswatch = Stopwatch.StartNew();
                                            ProductTestState[Step].St_Bluetooth_Address_Apply = false; // 为了适配蓝牙流程
                                            if (process.RetryDelayMs is not null and int RetryDelayMs)
                                            {
                                                await Task.Delay(RetryDelayMs);
                                            }
                                            else
                                            {
                                                await Task.Delay(600);
                                            }
                                            if (ProductTestState[Step].IsBluetoothBoard)
                                            {
                                                ExcuteCommand = ProductBlueCache.Write(ProductTestRecord[Step].Rc_CurrentApplyCommand.Trim());
                                            }
                                            else
                                            {
                                                ExcuteCommand = PowerPlantServer.Execute(ProductTestRecord[Step].Rc_CurrentApplyCommand.Trim());
                                            }
                                            ProductTestValue[Step].CurRetryCount++;
                                        }
                                        else
                                        {
                                            if (ProductTestRecord[Step].Rc_StepPossibleCause.Length > 0)
                                            {
                                                MessagePro?.Invoke(new Check(MessageProPlantType.Message | MessageProPlantType.Failed,
                                                $"{Step}->测试不通过,属性: {ProductTestRecord[Step].Rc_ExecuteAtrribute},\n\n: {ProductTestRecord[Step].Rc_StepPossibleCause}",
                                                WorkIndex));
                                            }
                                            else
                                            {
                                                MessagePro?.Invoke(new Check(MessageProPlantType.Message | MessageProPlantType.Failed,
                                                $"{Step}->测试不通过,属性: {ProductTestRecord[Step].Rc_ExecuteAtrribute}", WorkIndex));
                                            }

                                            await FlagVerify();

                                            isExeption = true;
                                            Safety_ProcessRunning.Push(false);
                                            break;
                                        }
                                    }
                                }
                                await Task.Delay(200);
                            }
                        }
                        else
                        {
                            TaskRelease(isExeption);
                            break;
                        }

                        if (Safety_ProcessRunning.TryPeek(out bool St_ProcessRunning) && !St_ProcessRunning)
                        {
                            MessagePro?.Invoke(new Check(MessageProPlantType.HeartBeats, "开始测试"));
                            MessagePro?.Invoke(new Check(MessageProPlantType.Message, "进程已停止"));
                            TaskRelease(isExeption);
                            break;
                        }

                        if (WorkIndex == multilAtrributes.Count)
                        {
                            MessagePro?.Invoke(new Check(MessageProPlantType.Message, "当前工序测试完成，进程已停止"));
                            MessagePro?.Invoke(new Check(MessageProPlantType.PushFinish, AdvanceInfo.IMEI));
                            MessagePro?.Invoke(new Check(MessageProPlantType.HeartBeats, "开始测试"));
                            TaskRelease(isExeption);
                        }
                    }
                }
            }); 
        }

        public async void Run(string content)
        {
            if (Safety_Step.TryPeek(out string? Step) && 
                Safety_ProcessRunning.TryPeek(out bool St_ProcessRunning) && St_ProcessRunning &&
                ProductTestState.TryGetValue(Step, out ActivityProductTestState? _ProductTestState) &&
                ProductTestRecord.TryGetValue(Step, out ActivityProductTestRecord? _ProductTestRecord) &&
                _ProductTestState.ReceiveAdvanceFlag)
            {
                if (!_ProductTestRecord.Rc_SerialPortoutPut.Contains(content)) _ProductTestRecord.Rc_SerialPortoutPut.Add(content);
                List<string> ConsultCollection = [.. _ProductTestRecord.Rc_SerialPortoutPut];
                try
                {
                    if (_ProductTestRecord.Rc_Atrribute is not null)
                    {
                        int cacheindex = ConsultCollection.Count;
                        for (int index = 0; index < cacheindex; index++)
                        {
                            string _content = ConsultCollection[index];
                            foreach (var Field in _ProductTestRecord.Rc_ValidFiedls)
                            {
                                if (Field.GetValue(_ProductTestRecord.Rc_Atrribute) is not null and object Value)
                                {
                                    switch (Field.Name)
                                    {
                                        case "PassFlag":

                                            List<string> keyword = [.. Regex.Split(Value.GetSafetyChar(), "\\s+")];

                                            if (!_ProductTestRecord.Rc_CollectedFields.Contains(Field.Name))
                                            {
                                                int contain = 0;
                                                foreach (var expect in keyword)
                                                {
                                                    int _contain = ConsultCollection.Where(x => x.Contains(expect)).Count();
                                                    if (_contain != 0) contain++;
                                                }
                                                
                                                if (contain == keyword.Count)
                                                {
                                                    _ProductTestRecord.Rc_CollectedFields.Add(Field.Name);
                                                    MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"匹配到通过标志: {keyword.Join("-")}"));
                                                }
                                            }
                                            break;

                                        case "PassMatch":
                                            string value = string.Empty;
       
                                            Match match = Regex.Match(_content, Value.GetSafetyChar(true));
                                            if (match.Groups.Count >= 2)
                                            {
                                                value = Regex.Match(_content, Value.GetSafetyChar(true)).Groups[1].Value;
                                            }
                                            else
                                            {
                                                value = Regex.Match(_content, Value.GetSafetyChar(true)).Groups[0].Value;
                                            }

                                            if (!string.IsNullOrEmpty(value) && 
                                                !_ProductTestRecord.Rc_CollectedFields.Contains(Field.Name))
                                            {
                                                value = value.Trim();
                                                if (_ProductTestState.IsHandDownValue) HandDownValue = value; //传承值
                                                TryAdd(_ProductTestRecord.Rc_CurrentApplyCommand, value);
                                                _ProductTestRecord.Rc_CollectedFields.Add(Field.Name);
                                                MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"匹配到通过值: {value}"));
                                            }

                                            break;

                                        case "PassValueVirify":

                                            if (!_ProductTestRecord.Rc_CollectedFields.Contains(Field.Name))
                                            {
                                                if (_ProductTestRecord.Rc_CachePassValue.TryGetValue(_ProductTestRecord.Rc_CurrentApplyCommand, out List<string>? passsValue))
                                                {
                                                    int indexof = passsValue.IndexOf(Value.GetSafetyChar().Trim());
                                                    if (indexof != -1)
                                                    {
                                                        _ProductTestRecord.Rc_CollectedFields.Add(Field.Name);
                                                    }
                                                    else
                                                    {
                                                        if (!_ProductTestRecord.Rc_CollectedFields.Contains("PassMatch"))
                                                        {
                                                            _ProductTestRecord.Rc_StepPossibleCause = "请检查是否正确设置了通过值匹配，当前匹配不通过";
                                                        }
                                                        else
                                                        {
                                                            _ProductTestRecord.Rc_StepPossibleCause = $"当前:{passsValue[indexof]} - 预期:{Value}，当前匹配不通过";
                                                        }
                                                    }
                                                }
                                            }
                                            break;

                                        case "ErrorFlag":

                                            if (_content.Contains(Value.GetSafetyChar()) && !_ProductTestRecord.Rc_CollectedFields.Contains(Field.Name))
                                            {
                                                Logger.DebudElite($"匹配到错误标志: {Value}->Content: {_content}");
                                            }
                                            break;

                                        case "AppendValue":

                                            if (!_ProductTestRecord.Rc_CollectedFields.Contains(Field.Name))
                                            {
                                                _ProductTestRecord.Rc_CollectedFields.Add(Field.Name);
                                                await CommandAppend(Value.GetSafetyChar());
                                                Logger.ErrorElite("append command start: ", _ProductTestState.St_DirectExecute);
                                            }
                                            break;

                                        case "MaxContentLength":
                                            if (!_ProductTestRecord.Rc_CollectedFields.Contains(Field.Name))
                                            {
                                                if (_ProductTestRecord.Rc_CachePassValue.TryGetValue(_ProductTestRecord.Rc_CurrentApplyCommand, out List<string>? passsValue))
                                                {
                                                    int totalindex = passsValue.Count;
                                                    int countindex = 0;
                                                    foreach (var pass in passsValue)
                                                    {
                                                        if (int.TryParse(Value.GetSafetyChar(), out int length))
                                                        {
                                                            if (pass.Length == length)
                                                            {
                                                                countindex++;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            _ProductTestRecord.Rc_StepPossibleCause = "请检查是否设置了通过值匹配，因为没有获取到上一个值";
                                                        }
                                                        
                                                    }
                                                    if (totalindex == countindex) _ProductTestRecord.Rc_CollectedFields.Add(Field.Name);
                                                }
                                            }
                                            break;

                                        case "ValidValueRange":
                                            if (!_ProductTestRecord.Rc_CollectedFields.Contains(Field.Name))
                                            {

                                                List<string> splits = [.. Regex.Split(Value.GetSafetyChar(), "\\W+")];
                                                if (splits.Count >= 2)
                                                {
                                                    if (int.TryParse(splits[0].Trim(), out int min) && int.TryParse(splits[1].Trim(), out int max))
                                                    {
                                                        int totalindex = _ProductTestRecord.Rc_ProcessValue.Count;
                                                        if (totalindex > 0)
                                                        {
                                                            int coutindex = 0;
                                                            foreach (var processing in _ProductTestRecord.Rc_ProcessValue)
                                                            {
                                                                if (int.TryParse(processing.Trim(), out int processValue))
                                                                {

                                                                    if (min <= processValue && processValue <= max)
                                                                    {
                                                                        
                                                                        MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"有效区间值校验: {min} {processValue} {max}"));
                                                                        coutindex++;
                                                                    }
                                                                    else
                                                                    {
                                                                        _ProductTestRecord.Rc_StepPossibleCause = $"有效值不符合预期, 值: {processValue}, 区间: {min}-{max}";
                                                                    }
                                                                }
                                                                else
                                                                {
                                                                    _ProductTestRecord.Rc_StepPossibleCause = "有效值提取有误，请检查是否设置了数据处理类型 或者 是否设置了通过值匹配";

                                                                }
                                                            }
                                                            if (coutindex == totalindex) _ProductTestRecord.Rc_CollectedFields.Add(Field.Name);
                                                        }
                                                    }
                                                    else
                                                    {
                                                        _ProductTestRecord.Rc_StepPossibleCause = "请检查区间数据类型输入是否有误";
                                                    }
                                                }
                                                else
                                                {
                                                    _ProductTestRecord.Rc_StepPossibleCause = "请检查区间格式设置是否有误";
                                                }
                                            }
                                            break;

                                        case "ValueProcessingType":
                                            if (_ProductTestRecord.Rc_CachePassValue.TryGetValue(_ProductTestRecord.Rc_CurrentApplyCommand, out List<string>? passs))
                                            {
                                                foreach (var pass in passs)
                                                {
                                                    string left = string.Empty;
                                                    string right = string.Empty;
                                                    List<string> splits = [.. Regex.Split(pass, "\\W+")];
                                                    if (splits.Count >= 2)
                                                    {
                                                        left = splits[0].Trim();
                                                        right = splits[1].Trim();
                                                    }

                                                    switch (Value.GetSafetyChar())
                                                    {
                                                        case "左值":
                                                            if (!string.IsNullOrEmpty(left) && !_ProductTestRecord.Rc_ProcessValue.Contains(left))
                                                            {
                                                                _ProductTestRecord.Rc_ProcessValue.Add(left);
                                                            }
                                                            break;

                                                        case "右值":
                                                            if (!string.IsNullOrEmpty(right) && !_ProductTestRecord.Rc_ProcessValue.Contains(right))
                                                            {
                                                                _ProductTestRecord.Rc_ProcessValue.Add(right);
                                                            }
                                                            break;

                                                        case "蓝牙":
                                                        case "整值":
                                                            if (!string.IsNullOrEmpty(pass.Trim()) && !_ProductTestRecord.Rc_ProcessValue.Contains(pass.Trim()))
                                                            _ProductTestRecord.Rc_ProcessValue.Add(pass.Trim());
                                                            break;
                                                    }
                                                }
                                            }

                                            break;

                                        case "IsLinkedToPrevious":
                                            if (!_ProductTestRecord.Rc_CollectedFields.Contains(Field.Name))
                                            {
                                                if (_ProductTestRecord.Rc_CachePassValue.TryGetValue(_ProductTestRecord.Rc_Atrribute.Command, out List<string>? passValue))
                                                {

                                                    if (HandDownValue is not null) passValue.Add(HandDownValue);

                                                    Logger.ErrorElite(passValue.Join(", "), "--", HandDownValue, _ProductTestState.IsHandDownValue);

                                                    if (passValue.Count(x=>x == HandDownValue) >= 2)
                                                    {
                                                        
                                                        string values = passValue.Join(" - ");
                                                        _ProductTestRecord.Rc_CollectedFields.Add(Field.Name);
                                                        MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"前后值: {values}"));
                                                    }
                                                    else
                                                    {
                                                        if (passValue.Count == 0)
                                                        {
                                                            _ProductTestRecord.Rc_StepPossibleCause = "请检查是否设置了通过值匹配，因为没有获取到上一个值";
                                                        }
                                                    }
                                                }
                                            }
                                            break;

                                        case "ContainAtthis":
                                            if (!_ProductTestRecord.Rc_CollectedFields.Contains(Field.Name))
                                            {
                                                string containValue = Value.GetSafetyChar().ToUpper();

                                                List<string> containValues = [.. Regex.Split(containValue, "[\\s+|\\s*,\\s*]").Select(x=>x.Trim())];

                                                List<string> matchContent = _content.MatchAll("[0-9a-zA-Z]{15,20}");

                                                int count = containValues.Count;

                                                int containPass = 0;

                                                foreach (var contain in containValues)
                                                {
                                                    bool UnEmpty = false;
                                                    switch (contain)
                                                    {
                                                        case "IMEI":
                                                            if (!string.IsNullOrEmpty(AdvanceInfo.IMEI))
                                                            {
                                                                UnEmpty = true;

                                                                if (matchContent.Contains(AdvanceInfo.IMEI))
                                                                {
                                                                    MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"IMEI: {AdvanceInfo.IMEI} 包含校验通过"));
                                                                    containPass++;
                                                                }
                                                            }
                                                            break;

                                                        case "SN":
                                                            if (!string.IsNullOrEmpty(AdvanceInfo.SN))
                                                            {
                                                                UnEmpty = true;

                                                                if (matchContent.Contains(AdvanceInfo.SN))
                                                                {
                                                                    MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"SN: {AdvanceInfo.SN} 包含校验通过"));
                                                                    containPass++;
                                                                }
                                                            }
                                                            break;

                                                        case "BLUE":
                                                            if (!string.IsNullOrEmpty(ProductBlueCache.Rc_CacheBluetoothAddress))
                                                            {
                                                                UnEmpty = true;

                                                                GroupCollection outputGroups = ProductBlueCache.Regex.Match(_content).Groups;
                                                                if (outputGroups.Count > 0)
                                                                {
                                                                    string[] outputSplit = Regex.Split(outputGroups[0].Value, "[:-]");
                                                                    string[] blueSplit = Regex.Split(ProductBlueCache.Rc_CacheBluetoothAddress, "[:-]");
                                                                    if (outputSplit.Equals(blueSplit))
                                                                    {
                                                                        MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"蓝牙地址: {ProductBlueCache.Rc_CacheBluetoothAddress} 包含校验通过"));
                                                                        containPass++;
                                                                    }
                                                                }
                                                            }
                                                            break;

                                                        case "DOID":
                                                            if (!string.IsNullOrEmpty(AdvanceInfo.DOID))
                                                            {
                                                                UnEmpty = true;

                                                                if (matchContent.Contains(AdvanceInfo.DOID))
                                                                {
                                                                    MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"DOID: {AdvanceInfo.DOID} 包含校验通过"));
                                                                    containPass++;
                                                                }
                                                            }
                                                            break;

                                                        case "QRCODE":
                                                            if (AdvanceInfo.QRCODE.Count > 0)
                                                            {
                                                                UnEmpty = true;

                                                                int qrIndex = 0;
                                                                foreach (var qr in AdvanceInfo.QRCODE)
                                                                {
                                                                    if (_content.Contains(qr)) qrIndex++;
                                                                    if (qrIndex == AdvanceInfo.QRCODE.Count)
                                                                    {
                                                                        MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"QR: {AdvanceInfo.QRCODE.Join(", ")} 包含校验通过"));
                                                                        containPass++;
                                                                    }
                                                                }
                                                            }
                                                            break;
                                                    }
                                                    if (!UnEmpty)
                                                    {
                                                        MessagePro?.Invoke(new Check(MessageProPlantType.Question, new CustomMessageBox.Field()
                                                        {
                                                            title = "参数为空",
                                                            type = 1,
                                                            message = "请进入参数设置界面选择或输入参数",
                                                            options = ["知道了"]
                                                        }));
                                                        Safety_ProcessRunning.Push(false);
                                                        break;
                                                    }
                                                }

                                                if (containPass == containValues.Count) _ProductTestRecord.Rc_CollectedFields.Add(Field.Name);
                                            }
                                            break;
                                        
                                        case "WriteDBFieldName":
                                            if (!_ProductTestRecord.Rc_CollectedFields.Contains(Field.Name))
                                            {

                                            }
                                            break;
                                    }
                                }
                            }

                            Logger.ErrorElite(_ProductTestRecord.Rc_CanCheckFields.Select(i => i.Name).Join("-"), _ProductTestRecord.Rc_CollectedFields.Join("+"));

                            if (_ProductTestRecord.Rc_CanCheckFields.Select(i => i.Name).Count()
                                ==
                                _ProductTestRecord.Rc_CollectedFields.Count &&
                                _ProductTestRecord.Rc_CanCheckFields.Select(i => i.Name).ToList()
                                .All(value => _ProductTestRecord.Rc_CollectedFields.Contains(value)))
                            {
                                Safety_StepRunning.Push(true);
                                _ProductTestRecord.Rc_StepPossibleCause = string.Empty;
                            }
                            else
                            {
                                var except = _ProductTestRecord.Rc_CanCheckFields.Select(i => i.Name).ToList().Except(_ProductTestRecord.Rc_CollectedFields);
                                if (except.Any() &&
                                    ActivityAssistBehivor.Behivor.fieldTranslationMap.TryGetValue(except.ElementAt(0), out string? translation) &&
                                    translation is not null)
                                {
                                    _ProductTestRecord.Rc_ExecuteAtrribute = translation;
                                }
                            }
                        }
                    }
                }
                catch (Exception runerror)
                {
                    if (runerror.Message.Contains("Invalid pattern") && _ProductTestRecord.Rc_Atrribute is not null && !_ProductTestState.St_RunCatch_Happend)
                    {
                        MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"当前流程 {_ProductTestRecord.Rc_Atrribute.Step} 正则有误"));
                        _ProductTestState.St_RunCatch_Happend = true;
                    }
                }
            }
        }

        public void TryAdd(string key, string value)
        {   
            if (Safety_Step.TryPeek(out string? Step) && ProductTestRecord.TryGetValue(Step, out ActivityProductTestRecord? _ProductTestRecord))
            {
                if (_ProductTestRecord.Rc_CachePassValue.TryGetValue(key, out List<string>? passs))
                {
                    passs.Add(value);
                }
                else
                {
                    _ProductTestRecord.Rc_CachePassValue.Add(key, [value]);
                }
            }
        }

        public void Recycle()
        {
            if (Safety_Step.TryPeek(out string? Step) && 
                ProductTestState.TryGetValue(Step, out ActivityProductTestState? _ProductTestState) &&
                ProductTestRecord.TryGetValue(Step, out ActivityProductTestRecord? _ProductTestRecord))
            {
                if (_ProductTestState.St_StepAwait || !_ProductTestState.St_DirectExecute)
                {
                    _ProductTestRecord.Rc_SerialPortoutPut.Clear();
                    _ProductTestState.St_DelAwait_Reset_Watch = !_ProductTestState.St_DirectExecute;
                    _ProductTestState.St_DirectExecute = !_ProductTestState.St_DirectExecute;
                    Logger.DebudElite($"recycle init: [St_DelAwait_Reset_Watch, {_ProductTestState.St_DelAwait_Reset_Watch}], " +
                                      $"[St_DirectExecute, {_ProductTestState.St_DirectExecute}]");
                }
            }
        }

        public void TaskRelease(bool isException)
        {
            if (Safety_Step.TryPeek(out string? Step) && ProductTestRecord.TryGetValue(Step, out ActivityProductTestRecord? _ProductTestRecord))
            {
                if (_ProductTestRecord.Rc_Atrribute is not null &&
                isException &&
                ActivityAssistBehivor.Behivor.LongTimeTak.Contains(_ProductTestRecord.Rc_CurrentApplyCommand))
                {
                    isLongTimeAtrribute = true;
                }
                else
                {
                    isLongTimeAtrribute = false;
                }
            }
            
            WorkIndex = 0;
            ProductBlueCache.Close(1);
            Safety_ProcessRunning.Push(false);
            if (ReuseOutTimer.IsEnabled) ReuseOutTimer.Stop();
            Logger.DebudElite("_release_end_");
        }

        public async Task CommandAppend(string value)
        {
            if (Safety_Step.TryPeek(out string? Step) && ProductTestState.TryGetValue(Step, out ActivityProductTestState? _ProductTestState) &&
                ProductTestRecord.TryGetValue(Step, out ActivityProductTestRecord? _ProductTestRecord) &&
                ProductTestValue.TryGetValue(Step, out ActivityProductTestValue? _ProductTestValue))
            {
                if (_ProductTestRecord.Rc_Atrribute is not null)
                {
                    bool IsAddtionXOR = false;
                    string AppendType = string.Empty;
                    if (_ProductTestRecord.Rc_Atrribute.IsaddtionXOR is not null and bool _IsaddtionXOR && _IsaddtionXOR)
                    {
                        IsAddtionXOR = _IsaddtionXOR;
                    }

                    if (_ProductTestRecord.Rc_Atrribute.AppendType is not null and string _AppendType)
                    {
                        AppendType = _AppendType;
                    }

                    List<string> CombinationCommands = [];

                    switch (AppendType)
                    {
                        case "蓝牙":

                            await ProductBlueCache.Match(value);

                            if (_ProductTestState.IsBluetoothBoard && !ProductBlueCache.BluetoothSerial.IsOpen)
                            {
                                await SelectionBlueSerialPort();

                                await OpenSelectionBlue();
                            }

                            if (value == "数据库") //不为空走设置流程
                            {
                                if (string.IsNullOrEmpty(ProductBlueCache.Rc_CacheBluetoothAddress))
                                {
                                    MessagePro?.Invoke(new Check(MessageProPlantType.Question, new CustomMessageBox.Field()
                                    {
                                        title = "数据库数据查找",
                                        message = "匹配数据为空，请选择或输入工单、IMEI",
                                        options = ["知道了"]
                                    }));

                                    Safety_ProcessRunning.Push(false);

                                    MessagePro?.Invoke(new Check(MessageProPlantType.Initialize, null));
                                }
                                else
                                {
                                    if (!string.IsNullOrEmpty(ProductBlueCache.Regex.Match(ProductBlueCache.Rc_CacheBluetoothAddress).Value))
                                    {
                                        string combine = Regex.Split(ProductBlueCache.Rc_CacheBluetoothAddress, "[:-]").Join(_ProductTestValue.CurBluethAccording);
                                        if (!_ProductTestRecord.Rc_CurrentApplyCommand.Contains(combine))
                                        {
                                            CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, combine];
                                            _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                            if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + combine.GetXORcode();
                                        }
                                    }
                                }
                                Recycle();
                            }
                            
                            else
                            {
                                Logger.ErrorElite("获取得字符", Step, _ProductTestValue.CurAddtionAccording);
                                if (string.IsNullOrEmpty(ProductBlueCache.Regex.Match(ProductBlueCache.Rc_CacheBluetoothAddress).Value))
                                {
                                    string randomBlue;
                                    if (_ProductTestValue.CurBluethAccording == "-")
                                    {
                                        randomBlue = 6.GetDesorderlyBlue(true);
                                    }
                                    else
                                    {
                                        randomBlue = 6.GetDesorderlyBlue();
                                    }
                                    string combine = Regex.Split(randomBlue, "[:-]").Join(_ProductTestValue.CurBluethAccording);
                                    // 使用正则判断，因为是随机的数值
                                    bool isAdded = string.IsNullOrEmpty(ProductBlueCache.Regex.Match(_ProductTestRecord.Rc_CurrentApplyCommand).Value);
                                    if (isAdded)
                                    {
                                        CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, combine];
                                        _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                        if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + combine.GetXORcode();
                                    }
                                    Recycle();

                                }
                                else
                                {
                                    string combine = Regex.Split(ProductBlueCache.Rc_CacheBluetoothAddress, "[:-]").Join(_ProductTestValue.CurBluethAccording);
                                    if (!_ProductTestRecord.Rc_CurrentApplyCommand.Contains(combine))
                                    {
                                        CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, combine];
                                        _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                        if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + combine.GetXORcode();
                                    }
                                    Recycle();
                                }
                            }
                            break;

                        case "序列号":
                            if (value == "数据库")
                            {
                                if (!_ProductTestRecord.Rc_CurrentApplyCommand.Contains(AdvanceInfo.SN))
                                {
                                    CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, AdvanceInfo.SN];
                                    _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                    if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + AdvanceInfo.SN.GetXORcode();
                                }
                            }
                            else
                            {
                                if (Regex.Match(value, "[0-9a-zA-Z]+").Length == value.Length)
                                {
                                    if (!_ProductTestRecord.Rc_CurrentApplyCommand.Contains(value))
                                    {
                                        CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, value];
                                        _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                        if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + value.GetXORcode();
                                    }
                                }
                            }
                            Recycle();
                            break;

                        case "IMEI号":

                            if (value == "数据库")
                            {
                                if (!_ProductTestRecord.Rc_CurrentApplyCommand.Contains(AdvanceInfo.IMEI))
                                {
                                    CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, AdvanceInfo.IMEI];
                                    _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                    if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + AdvanceInfo.IMEI.GetXORcode();
                                }
                            }
                            else
                            {
                                if (Regex.Match(value, "[0-9a-zA-Z]+").Length == value.Length)
                                {
                                    if (!_ProductTestRecord.Rc_CurrentApplyCommand.Contains(value))
                                    {
                                        CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, value];
                                        _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                        if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + value.GetXORcode();
                                    }
                                }
                            }
                            Recycle();
                            break;

                        case "DOID":

                            if (value == "数据库")
                            {
                                if (!_ProductTestRecord.Rc_CurrentApplyCommand.Contains(AdvanceInfo.DOID))
                                {
                                    CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, AdvanceInfo.DOID];
                                    _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                    if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + AdvanceInfo.DOID.GetXORcode();
                                }
                            }
                            else
                            {
                                if (Regex.Match(value, "[0-9a-zA-Z]+").Length == value.Length)
                                {
                                    if (!_ProductTestRecord.Rc_CurrentApplyCommand.Contains(value))
                                    {
                                        CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, value];
                                        _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                        if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + value.GetXORcode();
                                    }
                                }
                            }
                            Recycle();
                            break;

                        case "产品ID":
                            if (!_ProductTestRecord.Rc_CurrentApplyCommand.Contains(value))
                            {
                                CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, value];
                                _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + value.GetXORcode();
                            }
                            Recycle();
                            break;

                        case "产品密钥":
                            if (!_ProductTestRecord.Rc_CurrentApplyCommand.Contains(value))
                            {
                                CombinationCommands = [_ProductTestRecord.Rc_CurrentApplyCommand, value];
                                _ProductTestRecord.Rc_CurrentApplyCommand = CombinationCommands.Join(_ProductTestValue.CurAddtionAccording);
                                if (IsAddtionXOR) _ProductTestRecord.Rc_CurrentApplyCommand += "," + value.GetXORcode();
                            }
                            Recycle();
                            break;

                    }
                }
            }
        }

        public void Start(bool state = true)
        {
            if (state && WorkIndex != 0) WorkIndex = 0; //保险措施，有极小概率会导致索引延迟重置
            Safety_ProcessRunning.Push(state);
            if (Safety_Step.TryPeek(out string? Step) && ProductTestState.TryGetValue(Step, out ActivityProductTestState? _ProductTestState))
            {
                if (!state)
                {
                    _ProductTestState.St_DirectExecute = true;
                    _ProductTestState.St_DelAwait_Reset_Watch = true;
                    MessagePro?.Invoke(new Check(MessageProPlantType.Message, "正在停止流程..."));
                }
            }
        }

        public async Task FlagVerify()
        {
            await Task.Run(() =>
            {

                if (Safety_Step.TryPeek(out string? Step) &&
                    ProductTestRecord.TryGetValue(Step, out ActivityProductTestRecord? _ProductTestRecord))
                {
                    if (_ProductTestRecord.Rc_Atrribute is not null &&
                        _ProductTestRecord.Rc_Atrribute.Command.Contains("READ_FLAG"))
                    {
                        List<string> TestFlags = [.. ActivityAssistBehivor.Behivor.TestFlagsMap.Keys]; //字典key值集合
                        foreach (var pair in _ProductTestRecord.Rc_CachePassValue)
                        {
                            List<string> passValues = [.. pair.Value];

                            foreach (var _pass in passValues) //当前工序通过值
                            {
                                IEnumerable<string> matchFlags = TestFlags.Where(x => x.Contains(_pass)); // 通过值是否与标识字典key值匹配

                                if (matchFlags.Count() == 1)
                                {
                                    string matchFlag = matchFlags.ElementAt(0); //获取匹配字典key值
                                    (string, int) matchFlagValue = ActivityAssistBehivor.Behivor.TestFlagsMap[matchFlag]; //获取匹配字典value值
                                    string[] flagsplit = matchFlag.Split('-'); //分割

                                    if (flagsplit.Length == 2)
                                    {
                                        string behivor_flag = flagsplit[1]; // 字典标识
                                        string behivor_prdflag = flagsplit[0]; //字典标识名称
                                        string? current_flag = _ProductTestRecord.Rc_Atrribute.PassValueVirify; //当前工序标识
                                        string current_flagname = string.Empty; //当前工序标识名称
                                        int current_flag_order = -1;
                                        if (ActivityAssistBehivor.Behivor.TestFlagsMap.TryGetValue($"{AdvanceInfo.PRDFLAG}-{current_flag}", out (string, int) _flagArray))
                                        {
                                            current_flagname = _flagArray.Item1; //尝试查找当前工序标识名称名保存它
                                            current_flag_order = _flagArray.Item2; //尝试查找当前工序顺序并保存它
                                        }

                                        // 如果产品标识正确，并且当前步骤为校验设备标识，并且通过值与字典标识匹配，并且当前工序预期标识不匹配，开始组合可能原因信息
                                        if (behivor_prdflag == AdvanceInfo.PRDFLAG && _pass == behivor_flag && current_flag is not null && _pass != current_flag) // pass
                                        {
                                            //先给出笼统提示
                                            MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"当前标识 [{_pass} - {matchFlagValue.Item1}] " +
                                                $"与预期的 [{current_flag} - {current_flagname}] 标识不一致"));

                                            // 字典标识与预期标识, 
                                            if (current_flag_order != -1 && matchFlagValue.Item2 > current_flag_order)// 设备当前标识领先于预期标识
                                            {
                                                if (matchFlagValue.Item2 - current_flag_order == 1) // pass
                                                {
                                                    List<string> suplusStep = [];
                                                    IEnumerable<string> totalStep = ActivityAssistBehivor.Behivor.TestFlagsMap.Values
                                                        .Where(x => x.Item2 > matchFlagValue.Item2)
                                                        .Select(x => x.Item1);
                                                    foreach (var step in totalStep)
                                                    {
                                                        if (!suplusStep.Contains(step)) suplusStep.Add(step);
                                                    }

                                                    if (suplusStep.Count > 0) // 如果还存在剩余工序则提示
                                                    {
                                                        MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"当前工序 [{matchFlagValue.Item1}] 在预期工序 [{current_flagname}] 之后, " +
                                                            $"请选择剩余 [{suplusStep.Join("、")}] 工序进行测试"));
                                                    }
                                                    else //否则即为最终工序
                                                    {
                                                        MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"当前工序 [{matchFlagValue.Item1}] 在预期工序 [{current_flagname}] 之后, " +
                                                            $"当前已是最终工序，所有产测工序已完成"));
                                                    }
                                                }
                                                else
                                                {
                                                    List<string> suplusStep = [];
                                                    IEnumerable<string> totalStep1 = ActivityAssistBehivor.Behivor.TestFlagsMap.Values
                                                        .Where(x => x.Item2 < matchFlagValue.Item2 && x.Item2 > current_flag_order)
                                                        .Select(x => x.Item1);
                                                    foreach (var step in totalStep1)
                                                    {
                                                        if (!suplusStep.Contains(step)) suplusStep.Add(step);
                                                    }

                                                    List<string> expectStep = [];
                                                    IEnumerable<string> totalStep2 = ActivityAssistBehivor.Behivor.TestFlagsMap.Values
                                                        .Where(x => x.Item2 > matchFlagValue.Item2)
                                                        .Select(x => x.Item1);
                                                    foreach (var step in totalStep2)
                                                    {
                                                        if (!expectStep.Contains(step)) expectStep.Add(step);
                                                    }

                                                    MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"当前工序 [{matchFlagValue.Item1}] 和预期工序 [{current_flagname}] 非紧密工序, " +
                                                        $"差异 [{suplusStep.Join("、")}] 工序, 请选择 [{expectStep.Join("、")}] 工序进行测试"));
                                                }
                                            }
                                            else if (current_flag_order != -1 && matchFlagValue.Item2 < current_flag_order) // 设备当前标识落后于预期标识
                                            {
                                                if (matchFlagValue.Item2 - current_flag_order != 1)
                                                {
                                                    List<string> suplusStep = [];
                                                    IEnumerable<string> totalStep = ActivityAssistBehivor.Behivor.TestFlagsMap.Values
                                                        .Where(x => x.Item2 <= current_flag_order && x.Item2 > matchFlagValue.Item2)
                                                        .Select(x => x.Item1);
                                                    foreach(var step in totalStep)
                                                    {
                                                        if (!suplusStep.Contains(step)) suplusStep.Add(step);
                                                    }

                                                    MessagePro?.Invoke(new Check(MessageProPlantType.Message, $"当前工序 [{matchFlagValue.Item1}] 和预期工序 [{current_flagname}] 非紧密工序, " +
                                                        $"请先完成 [{suplusStep.Join("、")}] 工序后再执行当前工序"));
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            });
        }

        public bool State()
        {
            if (Safety_ProcessRunning.TryPeek(out bool St_ProcessRunning))
            {
                return St_ProcessRunning;
            }
            return false;
        }

        public void IsAwait(bool isAwait = true)
        {
            if (Safety_Step.TryPeek(out string? Step) && ProductTestState.TryGetValue(Step, out ActivityProductTestState? _ProductTestState))
            {
                _ProductTestState.St_StepAwait = isAwait;
            }
        }

        public void SendQuestioning(CustomMessageBox.Invoke invoke)
        {
            if (Safety_Step.TryPeek(out string? Step) && ProductTestRecord.TryGetValue(Step, out ActivityProductTestRecord? _ProductTestRecord))
            {
                _ProductTestRecord.QuestioningReturn = invoke;
            }
        }

        public async void SetMainAccording(string imei, string sn, string bluetooth, string doid, string? qr1, string? qr2)
        {
            async Task<bool> QR(string qr)
            {
                MessagePro?.Invoke(new Check(MessageProPlantType.DimProcess, new KeyValuePair<double, string>(1, "条码校验中...")));
                Dictionary<string, string> QRmap = await ExtraFromQrcode(qr);

                bool _verify = false;

                if (QRmap.TryGetValue("error", out string? _error))
                {
                    MessagePro?.Invoke(new Check(MessageProPlantType.Question, new CustomMessageBox.Field()
                    {
                        title = "参数错误",
                        type = 1,
                        message = $"条码信息中 [{_error}] 与 当前参数不一致",
                        options = ["知道了"]
                    }));
                    _verify = false;
                }

                if (QRmap.TryGetValue("id", out string? _id) &&
                    QRmap.TryGetValue("imei", out string? _imei) &&
                    QRmap.TryGetValue("sn", out string? _sn) &&
                    QRmap.TryGetValue("blue", out string? _blue))
                {
                    MessagePro?.Invoke(new Check(MessageProPlantType.DimProcess, new KeyValuePair<double, string>(5, "条码校验中...")));

                    if (_id != doid)
                    {
                        MessagePro?.Invoke(new Check(MessageProPlantType.Question, new CustomMessageBox.Field()
                        {
                            title = "参数错误",
                            type = 1,
                            message = $"条码ID [{_id}] 与 当前参数ID [{doid}] 不一致",
                            options = ["知道了"]
                        }));
                        _verify = false;
                    }

                    else if (_imei != imei)
                    {
                        MessagePro?.Invoke(new Check(MessageProPlantType.Question, new CustomMessageBox.Field()
                        {
                            title = "参数错误",
                            type = 1,
                            message = $"条码IMEI [{_imei}] 与 当前参数IMEI [{imei}] 不一致",
                            options = ["知道了"]
                        }));
                        _verify = false;
                    }

                    else if (_sn != sn)
                    {
                        MessagePro?.Invoke(new Check(MessageProPlantType.Question, new CustomMessageBox.Field()
                        {
                            title = "参数错误",
                            type = 1,
                            message = $"条码IMEI [{_sn}] 与 当前参数IMEI [{sn}] 不一致",
                            options = ["知道了"]
                        }));
                        _verify = false;
                    }

                    else if (_blue != bluetooth)
                    {
                        MessagePro?.Invoke(new Check(MessageProPlantType.Question, new CustomMessageBox.Field()
                        {
                            title = "参数错误",
                            type = 1,
                            message = $"条码IMEI [{_blue}] 与 当前参数IMEI [{bluetooth}] 不一致",
                            options = ["知道了"]
                        }));
                        _verify = false;
                    }
                    
                    else
                    {
                        _verify = true;
                    }
                }
                else
                {
                    _verify = false;
                }

                MessagePro?.Invoke(new Check(MessageProPlantType.DimProcess, new KeyValuePair<double, string>(10, "条码校验中...")));

                return _verify;
            }

            bool _pass = true;

            if (!string.IsNullOrEmpty(qr1))
            {
                _pass = await QR(qr1);
            }

            if (!string.IsNullOrEmpty(qr2))
            {
                _pass = await QR(qr2);
            }
            
            if (_pass)
            {
                await ProductBlueCache.Match(bluetooth);
                AdvanceInfo.IMEI = imei;
                AdvanceInfo.SN = sn;
                AdvanceInfo.DOID = doid;
                AdvanceInfo.QRCODE_1 = qr1;
                AdvanceInfo.QRCODE_2 = qr2;
            }
        }

        public void SetMainAccording(string productFlag)
        {
            AdvanceInfo.PRDFLAG = productFlag;
        }

        public async Task SelectionBlueSerialPort()
        {
            if (Safety_Step.TryPeek(out string? Step) && 
                ProductTestState.TryGetValue(Step, out ActivityProductTestState? _ProductTestState) &&
                ProductTestRecord.TryGetValue(Step, out ActivityProductTestRecord? _ProductTestRecord))
            {
                if (string.IsNullOrEmpty(ProductBlueCache.Rc_CacheBlueSerialPort) && !_ProductTestState.St_Bluetooth_SerialPort_Get)
                {
                    _ProductTestState.St_Bluetooth_SerialPort_Get = true;

                    ManagementObjectSearcher Cominfos = new(@"SELECT * FROM Win32_PnPEntity WHERE NAME LIKE '%COM%'");
                    List<string> SerialProts = [.. Cominfos.Com(Extendsion.CollectionType.t_ObservableCollection)];

                    MessagePro?.Invoke(new Check(MessageProPlantType.Question, new CustomMessageBox.Field()
                    {
                        title = "插上蓝牙板并选择它",
                        options = ["确定", "程序关闭前沿用这个蓝牙串口"],
                        itemsSource = SerialProts
                    }));

                    if (Safety_ProcessRunning.TryPeek(out bool St_ProcessRunning) && St_ProcessRunning)
                    {
                        while (St_ProcessRunning)
                        {
                            if (_ProductTestRecord.QuestioningReturn is not null && 
                                _ProductTestRecord.QuestioningReturn.selectedValues.Count > 0)
                            {
                                ProductBlueCache.Rc_CacheBlueSerialPort = Regex.Match(_ProductTestRecord.QuestioningReturn.selectedValues[0], @"(COM.*\d+)").Value;
                                break;
                            }
                            await Task.Delay(300);
                        }
                    }
                }
            }
        }

        private async Task OpenSelectionBlue()
        {
            await Task.Run(async () =>
            {
                if (Safety_Step.TryPeek(out string? Step) && 
                    ProductTestRecord.TryGetValue(Step, out ActivityProductTestRecord? _ProductTestRecord))
                {
                    if (Safety_ProcessRunning.TryPeek(out bool St_ProcessRunning))
                    {
                        Stopwatch stopwatch = Stopwatch.StartNew();
                        while (St_ProcessRunning && string.IsNullOrEmpty(ProductBlueCache.Rc_CacheBlueSerialPort))
                        {
                            await Task.Delay(200);

                            if (stopwatch.ElapsedMilliseconds > 5000) break;
                        }
                    }

                    try
                    {
                        if (!ProductBlueCache.BluetoothSerial.IsOpen)
                        {
                            ProductBlueCache.BluetoothSerial.PortName = ProductBlueCache.Rc_CacheBlueSerialPort;
                            ProductBlueCache.Open();
                            MessagePro?.Invoke(new Check(MessageProPlantType.Message,
                                               $"打开串口{ProductBlueCache.BluetoothSerial.PortName}, 状态: {ProductBlueCache.BluetoothSerial.IsOpen}"));
                        }

                        Logger.DebudElite("---", _ProductTestRecord.QuestioningReturn is not null &&
                            _ProductTestRecord.QuestioningReturn.index != 1);

                        if (_ProductTestRecord.QuestioningReturn is not null && 
                            _ProductTestRecord.QuestioningReturn.index != 1)
                        {
                            Logger.DebudElite("不沿用");
                            ProductBlueCache.Rc_CacheBlueSerialPort = string.Empty; // 不沿用
                        }
                        _ProductTestRecord.QuestioningReturn = null;

                    }
                    catch (Exception error)
                    {
                        _ProductTestRecord.QuestioningReturn = null;
                        _ProductTestRecord.Rc_StepPossibleCause = "检查:\n1.串口信息截取失败\n2.串口选择错误\n3.串口被占用";
                        Logger.ErrorElite($"blue serial open error: {error.Message}");
                    }
                }
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="qrcode"></param>
        /// <returns>(string, string, string, string) - id, imei, sn, blue</returns>
        public async Task<Dictionary<string, string>> ExtraFromQrcode(string qrcode)
        {
            WorkOrderUnfold? Add(object result)
            {
                WorkOrderUnfold? OrderUnfold = null;
                if (result is not null and Supabase.Postgrest.Responses.ModeledResponse<WorkOrderUnfold> cloudResult)
                {
                    foreach (var model in cloudResult.Models)
                    {
                        if (OrderUnfold == null)
                        {
                            OrderUnfold = model;
                        }
                        else
                        {
                            if (OrderUnfold.Imei != model.Imei)
                            {
                                OrderUnfold = null;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    if (result is not null and Dictionary<string, List<object>> localResult &&
                        localResult.Count > 0 &&
                        localResult.TryGetValue("id", out List<object>? ids) &&
                        localResult.TryGetValue("imei", out List<object>? imeis) &&
                        localResult.TryGetValue("sn", out List<object>? sns) &&
                        localResult.TryGetValue("blue_mac", out List<object>? blues))
                    {
                        for (int index = 0; index < ids.Count; index++)
                        {
                            if (OrderUnfold == null)
                            {
                                OrderUnfold = new WorkOrderUnfold 
                                {
                                    Id = ids[index].GetSafetyChar(),
                                    Imei = imeis[index].GetSafetyChar(),
                                    Sn = sns[index].GetSafetyChar(),
                                    BlueMac = blues[index].GetSafetyChar()
                                };
                            }
                            else
                            {
                                if (OrderUnfold.Imei != imeis[index].GetSafetyChar())
                                {
                                    OrderUnfold = null;
                                    break;
                                }
                            }
                        }
                    }
                }
                return OrderUnfold;
            }

            Dictionary<string, string> resultMap = [];
            List<string> matchKeyworks = qrcode.MatchAll("[0-9a-zA-Z]{15,20}");
            AdvanceInfo.QRCODE.Clear();

            foreach (var kw in matchKeyworks)
            {
                bool _stat = false;
                foreach (var flag in new List<string> { "IMEI", "SN" })
                {
                    
                    object? result = await ActivityDetatorServer.AutoFindDim(kw, flag);
                    if (result is not null)
                    {
                        if (Add(result) is not null and WorkOrderUnfold Unfold)
                        {
                            resultMap.TryAdd("id", Unfold.Id);
                            resultMap.TryAdd("imei", Unfold.Imei);
                            resultMap.TryAdd("sn", Unfold.Sn);
                            resultMap.TryAdd("blue", Unfold.BlueMac);
                        }
                        AdvanceInfo.QRCODE.Add(kw);
                        _stat = true;
                        break;
                    }
                }
                if (!_stat)
                {
                    resultMap.Clear();
                    resultMap.Add("error", kw) ;
                    break;
                }
            }
            return resultMap;
        }
    }
}
